

// promise简易版实现 只实现resolve和reject,then方法

class MyPromise{ //permise本质上就是一个类,使用resolve和reject去改变状态,用then去收集回调
    //构造函数
    constructor(executor){
        this.state = 'pending'; //定义promise的状态
        this.value = undefined; //定义promise的值
        this.reason = undefined; //定义promise的失败原因
        this.onFulfilledCallbacks = []; //定义成功回调,使用数组,可能有多个成功回调,就是对一个promise对象多次调用then方法
        this.onRejectedCallbacks = []; //定义失败回调,使用数组,可能有多个失败回调,就是对一个promise对象多次调用catch方法

        // 使用箭头函数确保this指向正确,定义在构造函数中是为了防止外部调用,只能在new的时候调用
        const resolve = (value) => { //定义resolve函数
            if(this.state === 'pending'){
                this.state = 'fulfilled'; //改变状态
                this.value = value; //改变值,将resolve的参数赋值给value
                this.onFulfilledCallbacks.forEach(callback => callback( this.value)); //执行成功回调
            }
        }

        const reject = (reason) => { //定义reject函数
            if(this.state === 'pending'){
                this.state = 'rejected'; //改变状态
                this.reason = reason; //改变失败原因,将reject的参数赋值给reason
                this.onRejectedCallbacks.forEach(callback => callback(this.reason)); //执行失败回调
            }
        }

        try {
            executor(resolve, reject); //执行传入的函数,executor是传递进来的函数,resolve和reject在传递进来的函数中进行调用    
        } catch (error) {
            reject(error); //如果传入的函数抛出错误,则调用reject函数
        }
    }

    // 将then方法定义在类的原型上,因为then方法是一个实例方法,所以需要定义在原型上
    then(onFulfilled, onRejected) { //定义then函数
        if(this.state === 'fulfilled'){
            onFulfilled(this.value);
        }
        if(this.state === 'rejected'){
            onRejected(this.reason);
        }
        if(this.state === 'pending'){ 
            //这里传入裸函数,不传入包装函数
            this.onFulfilledCallbacks.push(onFulfilled);
            this.onRejectedCallbacks.push(onRejected);
        }
    }
}

// ========== 测试例子：展示每一段代码的作用 ==========

const promise1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
     resolve("success");
  }, 1000);
})
promise1.then(res => {
    console.log("res",res); 
},err => {
    console.log("err",err);
}) 


const promise2 = new MyPromise((resolve,reject) => {
    resolve("success");
})
promise2.then(res => {
    console.log("res1",res);
})
promise2.then(res => {
    console.log("res2",res);
})



